﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Windows;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;



namespace vJine.Lua.GUI.UI {
    public class PlotHelper {
        static OxyColor parse_color(string name) {
            FieldInfo fColor = typeof(OxyColors).GetField(name, BindingFlags.Public | BindingFlags.Static);
            return (OxyColor)fColor.GetValue(null);
        }
        public static void reg(LuaContext context) {
            context.reg("ui.plot", new Action<PlotData>((PlotData data) => {
                PlotModel pmOxy = new PlotModel { Title = data.title };
                if (data.margin != null) {
                    pmOxy.PlotMargins =
                        new OxyThickness(data.margin[0], data.margin[1], data.margin[2], data.margin[3]);
                }

                //坐标轴
                for (int i = 0, len = data.axes.Count; i < len; i++) {
                    PlotData.Axis axis_i = data.axes[i];

                    LinearAxis la_i =
                        new LinearAxis { 
                            Key = axis_i.name, Title = axis_i.title,
                            AxisDistance = axis_i.offset, AxisTitleDistance = -axis_i.offset
                        };
                    if (!string.IsNullOrEmpty(axis_i.color)) {
                        la_i.TitleColor = parse_color(axis_i.color);
                    }
                    switch (axis_i.pos) {
                        case "left":
                            la_i.Position = AxisPosition.Left;
                            break;
                        case "top":
                            la_i.Position = AxisPosition.Top;
                            break;
                        case "right":
                            la_i.Position = AxisPosition.Right;
                            break;
                        case "bottom":
                            la_i.Position = AxisPosition.Bottom;
                            break;
                        default:
                            break;
                    }

                    if (axis_i.max > axis_i.min) {
                        la_i.Minimum = axis_i.min; 
                        la_i.Maximum = axis_i.max;
                    }
                    pmOxy.Axes.Add(la_i);
                }
                //数据系列
                for (int i = 0, len = data.series.Count; i < len; i++) {
                    PlotData.Sery ser_i = data.series[i];
                    LineSeries ls_i = new LineSeries { XAxisKey = ser_i.x, YAxisKey = ser_i.y };
                    if (!string.IsNullOrEmpty(ser_i.color)) {
                        ls_i.Color = parse_color(ser_i.color);
                    }
                    int rowStart = 
                        ser_i.row_start != null ? ser_i.row_start.Value - 1 : 0;
                    int rowStop = 
                        ser_i.row_stop != null ? ser_i.row_stop.Value - 1 : ser_i.data.Count - 1;
                    int xIndex = 
                        ser_i.x_index != null ? ser_i.x_index.Value - 1 : 0;
                    int yIndex = 
                        ser_i.y_index != null ? ser_i.y_index.Value - 1 : 1;
                    for (int l = rowStart; l <= rowStop; l++) {
                        double[] d = ser_i.data[l];
                        ls_i.Points.Add(new DataPoint(d[xIndex], d[yIndex]));
                    }

                    pmOxy.Series.Add(ls_i);
                }

                WinPlot winPlotter = new WinPlot() { pmOxy = pmOxy, WindowStartupLocation = WindowStartupLocation.CenterScreen };
                if (data.width > 0) {
                    winPlotter.Width = data.width;
                }
                if (data.height > 0) {
                    winPlotter.Height = data.height;
                }

                winPlotter.ShowDialog();
                if (!string.IsNullOrEmpty(data.file)) {
                    winPlotter.save_pic(data.file);
                }
            }));
        }
    }

    public class PlotData {
        public string title { get; set; }

        public double width { get; set; }
        public double height { get; set; }

        public double offset { get; set; }
        public List<double> margin { get; set; }


        public List<Axis> axes { get; set; }
        public List<Sery> series { get; set; }

        public string file { get; set; }

        public class Axis {
            public string name { get; set; }
            public string title { get; set; }
            public string pos { get; set; }
            public double offset { get; set; }
            public string color { get; set; }
            public double min { get; set; }
            public double max { get; set; }
        }

        public class Sery {
            public string x { get; set; }
            public string y { get; set; }

            public int? row_start { get; set; }
            public int? row_stop { get; set; }
            public int? x_index { get; set; }
            public int? y_index { get; set; }

            public bool smooth { get; set; }
            public string color { get; set; }
            public List<double[]> data { get; set; }
        }
    }
}
